/* ================================================================================
//	Crypteviant!
//	Providing tough encrypted P2P Chat
//	Copyright (C) 2010  Martin Pfeifer, Tobias Rausch
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ============================================================================== */

#include "entropypoolmanager.hpp"

using namespace RandomPool;


// Initialize static variables
EntropyPoolManager* EntropyPoolManager::m_instance = NULL;


const EntropyPoolManager * const EntropyPoolManager::getInstance()
{
    // Check if already an instance exists
    if (m_instance == NULL)
    {
        m_instance = new EntropyPoolManager();
    }

    return m_instance;
}


EntropyPoolManager::EntropyPoolManager(QObject *parent) :
    QThread(parent)
{
    qRegisterMetaType<EntropyDataStruct>("EntropyDataStruct");

    m_pools.clear();
}


EntropyPoolManager::~EntropyPoolManager()
{
    // Delete all Pools
    qDeleteAll(m_pools);
}


void EntropyPoolManager::run()
{
    // Generate the Pools
    for (unsigned int i = 0; i < POOLCOUNT; i++)
    {
        EntropyPool *pool = new EntropyPool();
        pool->setProperty("id", QVariant(i));
        m_pools.insert(i, pool);
    }

    qDebug() << "EntropyPoolManager running in Thread " + QString::number((int) currentThreadId(), 16);

    // Start the event loop
    exec();
}


void EntropyPoolManager::addData(EntropyDataStruct data)
{
    // Make sure that poolId is in range
    unsigned int poolId = data.poolId % POOLCOUNT;

    // Check if the Pool exists
    if (!m_pools.contains(poolId))
    {
        return;
    }

    // Check if the data is too old
    if ( QDateTime::currentMSecsSinceEpoch() > (data.timestamp + MAXLIFETIME) )
    {
        return;
    }

    // Get the specified Pool and add the data
    EntropyPool *pool = m_pools.value(poolId);
    pool->addData(data.data);

    qDebug() << "Added Data to Pool " + QString::number(poolId);
    qDebug() << "Data: " + data.data;
    qDebug() << "Retrieved from Source " + QString::number(data.sourceId);
}
